export const isObject = item => Object.prototype.toString.call(item) === '[object Object]';
export const isArray = item => Object.prototype.toString.call(item) === '[object Array]';

const routers = ['switchTab', 'reLaunch', 'redirectTo', 'navigateTo', 'navigateBack'];


export default class AniRouter {
	constructor() {
		this.routerConfig = [];
		this.init();
	}

	init() {
		this.proxyRouter();
	}

	setRouterIntercept(data) {
		if (isArray(data)) {
			this.routerConfig = [...this.routerConfig, ...data];
		} else if (isObject(data)) {
			this.routerConfig.push(data);
		}
	}

	setRouterListen(data) {
		if (!isObject(data)) throw new Error('类型错误');
		this.routerConfig.push(data);
	}

	proxyRouter() {
		routers.forEach(router => {
			const originalMethod = wx[router];
			wx[router] = (data) => {
				if (data.proxy === false) return originalMethod(data);

				const shouldIntercept = this.handleInterceptions(data, router);
				if (shouldIntercept) return;

				originalMethod(data);
			};
		});
	}

	handleInterceptions({ url, ...rest }, routerType) {
		const currentPage = getCurrentPages().pop();

		if (currentPage.$beforeRouter && currentPage.$beforeRouter({ url, routerType, beforePage: currentPage }) === false) {
			return true;
		}

		for (const config of this.routerConfig) {
			if (!this.matchRouterConfig(url, config)) continue;

			if (config.before && config.before.call(currentPage, { routerType, url, ...rest }) === false) {
				return true;
			}

			const originalSuccess = rest.success;
			rest.success = (...args) => {
				setTimeout(() => config.after?.call(currentPage, { url, ...rest }), 300);
				originalSuccess?.apply(this, args);
			};
		}

		return false;
	}

	matchRouterConfig(url, { url: configUrl }) {
		if (typeof configUrl === 'string') {
			return url.includes(configUrl);
		}
		if (isArray(configUrl)) {
			return configUrl.some(u => url.includes(u));
		}
		return false;
	}
}
